package com.demo.study.behavior.inbound;

import com.demo.study.behavior.inbound.dto.InboundApplication;
import com.demo.study.behavior.inbound.handler.DoaDapHandler;
import com.demo.study.behavior.inbound.handler.FcrmHandler;
import com.demo.study.behavior.inbound.handler.NormalHandler;
import com.demo.study.behavior.inbound.handler.PrototypeHandler;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 入库实现
 *
 * @author Baymax
 * @since 2022/3/25
 */
public class InboundInvoker {
    private List<Handler> handlers = new ArrayList<>();

    private List<InboundApplication> inboundApplications;

    public InboundInvoker(List<InboundApplication> inboundApplications) {
        this.inboundApplications = inboundApplications;
        initHandler();
    }

    private void initHandler() {
        handlers.add(new DoaDapHandler(inboundApplications));
        handlers.add(new FcrmHandler(inboundApplications));
        handlers.add(new PrototypeHandler(inboundApplications));
    }

    /**
     * 开始执行操作
     */
    public void invoke() {
        for (Handler handler : handlers) {
            if (handler.needExecute()) {
                removeFromParent(handler.getApplications());
                List<String> businessIds = doSplit(handler.getApplications());
                handler.execute(businessIds);
                System.out.println();
            }
        }
        NormalHandler normalHandler = new NormalHandler(inboundApplications);
        if (normalHandler.needExecute()) {
            normalHandler.execute(doSplit(normalHandler.getApplications()));
        }
    }

    /**
     * 从集合中移除子类的申请但
     *
     * @param applications 需要移除的入库单
     */
    private void removeFromParent(List<InboundApplication> applications) {
        List<String> applicationNos = applications.stream().map(InboundApplication::getApplicationNo)
            .collect(Collectors.toList());
        for (int i = this.inboundApplications.size() - 1; i >= 0; i--) {
            if (applicationNos.contains(inboundApplications.get(i).getApplicationNo())) {
                inboundApplications.remove(i);
            }
        }
    }

    private List<String> doSplit(List<InboundApplication> inboundApplications) {
        return inboundApplications.stream().map(InboundApplication::getBusinessId).collect(Collectors.toList());
    }
}
